#include "../include/uart.h"
    #include "../include/stdint.h"

    // UART 16550 寄存器地址
    #define UART_BASE 0x10000000
    #define UART_RHR  (UART_BASE + 0) // 接收保持寄存器
    #define UART_THR  (UART_BASE + 0) // 发送保持寄存器
    #define UART_IER  (UART_BASE + 1) // 中断使能寄存器
    #define UART_FCR  (UART_BASE + 2) // FIFO控制寄存器
    #define UART_LCR  (UART_BASE + 3) // 线路控制寄存器
    #define UART_LSR  (UART_BASE + 5) // 线路状态寄存器

    // UART 线路控制寄存器位定义
    #define UART_LCR_BAUD_LATCH 0x80 // 波特率锁存位
    #define UART_LCR_EIGHT_BITS 0x03 // 8位数据位

    // UART FIFO控制寄存器位定义
    #define UART_FCR_FIFO_EN    0x01 // 启用FIFO
    #define UART_FCR_CLEAR_FIFO 0x06 // 清空FIFO

    // UART 中断使能寄存器位定义
    #define UART_IER_RX_ENABLE  0x01 // 接收中断使能
    #define UART_IER_TX_ENABLE  0x02 // 发送中断使能

    // UART 线路状态寄存器位定义
    #define UART_LSR_RX_READY   0x01 // 接收数据就绪
    #define UART_LSR_TX_IDLE    0x20 // 发送缓冲区空闲

    // 读写UART寄存器的辅助函数
    static inline uint8_t uart_read(int reg) {
        return *(volatile uint8_t *)reg;
    }

    static inline void uart_write(int reg, uint8_t data) {
        *(volatile uint8_t *)reg = data;
    }

    void uart_init(void) {
        // 禁用中断
        uart_write(UART_IER, 0x00);

        // 设置波特率（38400）
        uart_write(UART_LCR, UART_LCR_BAUD_LATCH);
        uart_write(UART_RHR, 0x03);  // 波特率除数低位
        uart_write(UART_IER, 0x00);  // 波特率除数高位

        // 设置数据格式: 8位数据, 1位停止位, 无奇偶校验
        uart_write(UART_LCR, UART_LCR_EIGHT_BITS);

        // 启用并清空FIFO
        uart_write(UART_FCR, UART_FCR_FIFO_EN | UART_FCR_CLEAR_FIFO);

        // 启用接收和发送中断
        uart_write(UART_IER, UART_IER_RX_ENABLE | UART_IER_TX_ENABLE);
    }

    void uart_putc(char c) {
        // 等待发送缓冲区空闲
        while ((uart_read(UART_LSR) & UART_LSR_TX_IDLE) == 0);
        
        // 发送字符
        uart_write(UART_THR, c);
    }

    void uart_puts(char *s) {
        for (int i = 0; s[i] != '\0'; i++) {
            // 处理换行，添加回车
            if (s[i] == '\n') {
                uart_putc('\r');
            }
            uart_putc(s[i]);
        }
    }